using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

using SIMA.Entities;
using SIMA.Core.Data.Collection;
using SIMA.Core.Data.Access;
using SIMA.Core.Enums;
using SIMA.Core.EventArgs;
using SIMA.Core.Security;

namespace SIMA.Services
{

	public class T_C_TablaService : IT_C_TablaService
	{
		#region Fields

		private SmartContainer<T_C_Tabla> dataAccessSmart;
		private FailedEventArgs onFailed;
		private InsertedEventArgs onInserted;
		private UpdatedEventArgs onUpdated;
		private DeletedEventArgs onDeleted;
		private static Semaphore ResourceLock;
        private FilterType filter;
        private T_C_Tabla tmpTabla1, tmpTabla2;

		#endregion

		#region Constructor

		public T_C_TablaService()
		{
			DataAccess.SetConnection(SIMA.Core.Enums.AccessType.FromString, "Data Source=.;Initial Catalog=SIMA;Integrated Security=True");
			ResourceLock = new Semaphore(0, 2);
			dataAccessSmart = new SmartContainer<T_C_Tabla>(false,true);
			dataAccessSmart.Inserted += new EventHandler<InsertedEventArgs>(dataAccessSmart_Inserted);
			dataAccessSmart.Failed += new EventHandler<FailedEventArgs>(dataAccessSmart_Failed);
			dataAccessSmart.Updated += new EventHandler<UpdatedEventArgs>(dataAccessSmart_Updated);
			dataAccessSmart.Deleted += new EventHandler<DeletedEventArgs>(dataAccessSmart_Deleted);
		}

		#endregion

		#region Implementacion de eventos del SmartContainer

        private void dataAccessSmart_Inserted(object sender, InsertedEventArgs e)
        {
            onInserted = e;
        }

        private void dataAccessSmart_Updated(object sender, UpdatedEventArgs e)
        {
            onUpdated = e;
        }

        private void dataAccessSmart_Deleted(object sender, DeletedEventArgs e)
        {
            onDeleted = e;
        }

        private void dataAccessSmart_Failed(object sender, FailedEventArgs e)
        {
            onFailed = e;
        }

		#endregion

		#region Implementando la interfaz de servicio

		public List<T_C_Tabla> GetAllT_C_Tabla(Profile securityProfile)
		{
			SecurityProgram.PcProfile = securityProfile;
			dataAccessSmart.SelectAll();
			return dataAccessSmart.ToList();
		}

		public IAsyncResult BeginGetAllT_C_Tabla(Profile securityProfile, AsyncCallback callback, object state)
		{
			T_C_TablaAsyncResult asyncResult = new T_C_TablaAsyncResult(securityProfile, callback, state);
			ThreadPool.QueueUserWorkItem(new WaitCallback((GetAllT_C_TablaCallback)), asyncResult);
			return asyncResult;
		}

		private void GetAllT_C_TablaCallback(object asyncResult)
		{
			T_C_TablaAsyncResult getT_C_TablaAsyncResult = (T_C_TablaAsyncResult)asyncResult;
			try
			{
				getT_C_TablaAsyncResult.CollectionResult = GetAllT_C_Tabla(SecurityProgram.PcProfile);
				getT_C_TablaAsyncResult.ExceptionTrace = null;
				getT_C_TablaAsyncResult.MessageResult = string.Empty;
			}
			catch(Exception ex)
			{
				getT_C_TablaAsyncResult.CollectionResult = null;
				getT_C_TablaAsyncResult.ExceptionTrace = ex;
				getT_C_TablaAsyncResult.MessageResult = string.Empty;
			}
			finally
			{
				getT_C_TablaAsyncResult.OnCompleted();
			}
		}

		public List<T_C_Tabla> EndGetAllT_C_Tabla(IAsyncResult asyncResult)
		{
			List<T_C_Tabla> lista = null;
			using(T_C_TablaAsyncResult getT_C_TablaResult = asyncResult as T_C_TablaAsyncResult)
			{
				getT_C_TablaResult.AsyncWaitHandle.WaitOne();
				lista = getT_C_TablaResult.CollectionResult;
			}
			return lista;
		}

	   public List<T_C_Tabla> GetFilteredT_C_Tabla(Profile securityProfile, FilterType filter)
        {
            List<T_C_Tabla> lista = null;
            this.filter = filter;
            SecurityProgram.PcProfile = securityProfile;
            switch (filter)
            {
                case FilterType.Active:
                    lista = dataAccessSmart["SelectActiveTabla", CommandType.StoredProcedure];
                    break;
                case FilterType.Inactive:
                    lista = dataAccessSmart["SelectInactiveTabla", CommandType.StoredProcedure];
                    break;
            }
            return lista;
        }

        public IAsyncResult BeginGetFilteredT_C_Tabla(Profile securityProfile, FilterType filter, AsyncCallback callback, object state)
        {
            T_C_TablaAsyncResult asyncResult = new T_C_TablaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((GetFilteredT_C_TablaCallback)), asyncResult);
            return asyncResult;
        }

        private void GetFilteredT_C_TablaCallback(object asyncResult)
        {
            T_C_TablaAsyncResult getT_C_TablaAsyncResult = (T_C_TablaAsyncResult)asyncResult;
            try
            {
                getT_C_TablaAsyncResult.CollectionResult = GetFilteredT_C_Tabla(SecurityProgram.PcProfile, this.filter);
                getT_C_TablaAsyncResult.ExceptionTrace = null;
                getT_C_TablaAsyncResult.MessageResult = string.Empty;
            }
            catch (Exception ex)
            {
                getT_C_TablaAsyncResult.CollectionResult = null;
                getT_C_TablaAsyncResult.ExceptionTrace = ex;
                getT_C_TablaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                getT_C_TablaAsyncResult.OnCompleted();
            }
        }
///
        public List<T_C_Tabla> EndGetFilteredT_C_Tabla(IAsyncResult asyncResult)
        {
            List<T_C_Tabla> lista = null;
            using (T_C_TablaAsyncResult getT_C_TablaResult = asyncResult as T_C_TablaAsyncResult)
            {
                getT_C_TablaResult.AsyncWaitHandle.WaitOne();
                lista = getT_C_TablaResult.CollectionResult;
            }
            return lista;
        }

        #endregion

        #region New

        public string RegisterT_C_Tabla(Profile securityProfile, T_C_Tabla newItem)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpTabla1 = newItem;
            dataAccessSmart.Add(newItem);
            ResourceLock.WaitOne(1000);
            return "Nuevo registro de tabla creado.";
        }

        public IAsyncResult BeginRegisterT_C_Tabla(Profile securityProfile, T_C_Tabla newItem, AsyncCallback callback, object state)
        {
            T_C_TablaAsyncResult asyncResult = new T_C_TablaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((RegisterT_C_TablaCallback)), asyncResult);
            return asyncResult;
        }

        private void RegisterT_C_TablaCallback(object asyncResult)
        {
            T_C_TablaAsyncResult t_c_TablaAsyncResult = (T_C_TablaAsyncResult)asyncResult;
            try
            {
                t_c_TablaAsyncResult.CollectionResult = null;
                t_c_TablaAsyncResult.ExceptionTrace = null;
                t_c_TablaAsyncResult.MessageResult = RegisterT_C_Tabla(SecurityProgram.PcProfile, tmpTabla1);

            }
            catch (Exception ex)
            {
                t_c_TablaAsyncResult.CollectionResult = null;
                t_c_TablaAsyncResult.ExceptionTrace = ex;
                t_c_TablaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_TablaAsyncResult.OnCompleted();
                tmpTabla1 = null;
            }
        }

        public string EndRegisterT_C_Tabla(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_TablaAsyncResult t_c_TablaAsyncResult = asyncResult as T_C_TablaAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_TablaAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion

        #region Update

        public string UpdateT_C_Tabla(Profile securityProfile, T_C_Tabla itemToUpdate, T_C_Tabla itemUpdated)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpTabla1 = itemToUpdate;
            tmpTabla2 = itemUpdated;
            dataAccessSmart.Update(tmpTabla1, tmpTabla2);
            ResourceLock.WaitOne(1000);
            return "Cambio de tabla realizado.";
        }

        public IAsyncResult BeginUpdateT_C_Tabla(Profile securityProfile, T_C_Tabla itemToUpdate, T_C_Tabla itemUpdated, AsyncCallback callback, object state)
        {
            T_C_TablaAsyncResult asyncResult = new T_C_TablaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((UpdateT_C_TablaCallback)), asyncResult);
            return asyncResult;
        }

        private void UpdateT_C_TablaCallback(object asyncResult)
        {
            T_C_TablaAsyncResult t_c_TablaAsyncResult = (T_C_TablaAsyncResult)asyncResult;
            try
            {
                t_c_TablaAsyncResult.CollectionResult = null;
                t_c_TablaAsyncResult.ExceptionTrace = null;
                t_c_TablaAsyncResult.MessageResult = UpdateT_C_Tabla(SecurityProgram.PcProfile, tmpTabla1, tmpTabla2);

            }
            catch (Exception ex)
            {
                t_c_TablaAsyncResult.CollectionResult = null;
                t_c_TablaAsyncResult.ExceptionTrace = ex;
                t_c_TablaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_TablaAsyncResult.OnCompleted();
                tmpTabla1 = null;
                tmpTabla2 = null;
            }
        }

        public string EndUpdateT_C_Tabla(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_TablaAsyncResult t_c_TablaAsyncResult = asyncResult as T_C_TablaAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_TablaAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion

        #region Delete

        public string DeleteT_C_Tabla(Profile securityProfile, T_C_Tabla dropItem)
        {
            SecurityProgram.PcProfile = securityProfile;
            tmpTabla1 = dropItem;
            dataAccessSmart.Remove(dropItem);
            ResourceLock.WaitOne(1000);
            return "Baja de tabla realizada.";
        }

        public IAsyncResult BeginDeleteT_C_Tabla(Profile securityProfile, T_C_Tabla dropItem, AsyncCallback callback, object state)
        {
            T_C_TablaAsyncResult asyncResult = new T_C_TablaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((DeleteT_C_TablaCallback)), asyncResult);
            return asyncResult;
        }

        private void DeleteT_C_TablaCallback(object asyncResult)
        {
            T_C_TablaAsyncResult t_c_TablaAsyncResult = (T_C_TablaAsyncResult)asyncResult;
            try
            {
                t_c_TablaAsyncResult.CollectionResult = null;
                t_c_TablaAsyncResult.ExceptionTrace = null;
                t_c_TablaAsyncResult.MessageResult = DeleteT_C_Tabla(SecurityProgram.PcProfile, tmpTabla1);

            }
            catch (Exception ex)
            {
                t_c_TablaAsyncResult.CollectionResult = null;
                t_c_TablaAsyncResult.ExceptionTrace = ex;
                t_c_TablaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_TablaAsyncResult.OnCompleted();
                tmpTabla1 = null;
            }
        }

        public string EndDeleteT_C_Tabla(IAsyncResult asyncResult)
        {
            string msg = string.Empty;
            using (T_C_TablaAsyncResult t_c_TablaAsyncResult = asyncResult as T_C_TablaAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_TablaAsyncResult.MessageResult;
            }
            return msg;
        }

        #endregion    

		
	}
}
